/* -------------------- */
/** 泛型接口 + TS泛型约束 + 多态 组合应用
 * 多态 体现在： 1. 父类对象变量可以接受任何它的子类对象
 * 2. 接口类型对象变量可以接受任何它的实现类的对象
 * **/

// 定义一个泛型接口
interface ArrayInerface<T> {
  add(ele: T): void
  get(index: number): T
  size(): number
  remove(index): void
}
// 泛型接口约束
class LinkArray<T> implements ArrayInerface<T> {
  list:Array<T> = []
  constructor() {}
  add(ele: T): void {
    this.list.push(ele)
  }
  get(index: number): T {
    return this.list[index]
  }
  size(): number {
    return this.list.length
  }
  remove(index: number): void {
    this.list.splice(index, 0)
  }
}

// 定义一个车辆父类
class Vechile {
  constructor(public name:string, public price:number, public license:string, public num:number) {
    this.name = name // 车名
    this.price = price // 车价
    this.license = license // 牌照
    this.num = num // 数量
  }
  // 计算购买这些车需要多少钱
  calcPrice(): number {
    return this.num * this.price
  }
}
// 定义一个Bus类，继承Vechile父类
class Bus extends Vechile {
  calcPrice(): number {
    // 折扣1000
    return this.num * this.price - 1000
  }
}
// 定义一个Trunck类，继承Vechile父类
class Trunck extends Vechile {
  calcPrice(): number {
    // 折扣2000
    return this.num * this.price - 2000
  }
}
// 定义客户类
class Customer {
  // 租那些车需要多少钱
  rent<T extends object>(list: ArrayInerface<T>) {
    let total = 0
    for(let i = 0; i < list.size(); i++) {
      total += (list.get(i) as any).calcPrice()
    }
    return total
  }
}
let rentList:ArrayInerface<Vechile> = new LinkArray<Vechile>()
rentList.add(new Bus('吉利', 5000, '京133DF', 1))
rentList.add(new Trunck('比亚迪', 3000, '京234FQ', 2))
let cust = new Customer()
let totalPrice = cust.rent<Vechile>(rentList)
console.log('当前租车费用：' + totalPrice)

export default {}